package com.yn.pet.controller.app.biz;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yn.common.core.domain.entity.SysDictData;
import com.yn.pet.bus.entity.DeviceInfo;
import com.yn.pet.bus.entity.PhoneWhitelist;
import com.yn.pet.bus.enums.DeviceStatusEnum;
import com.yn.pet.controller.pc.request.PhoneWhiteListRequest;
import com.yn.pet.controller.pc.response.NoticeTypeResponse;
import com.yn.pet.controller.pc.response.PhoneWhiteListResponse;
import com.yn.pet.controller.tcpserver.PetServer808Service;
import com.yn.pet.entity.AppUser;
import com.yn.pet.protocol.t808.T0001;
import com.yn.pet.protocol.t808.T8401;
import com.yn.pet.service.DeviceInfoService;
import com.yn.pet.service.PhoneWhitelistService;
import com.yn.pet.util.AppTokenUtil;
import com.yn.pet.util.PhoneUtil;
import com.yn.system.service.ISysDictDataService;
import io.github.yezhihao.netmc.core.annotation.Async;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class APhoneWhiteListBizService {

    private final PetServer808Service petServer808Service;

    private final PhoneWhitelistService phoneWhitelistService;

    private final DeviceInfoService deviceInfoService;

    private final ISysDictDataService dictDataService;


    /**
     * 添加联系人白名单
     * @param request 请求参数
     */
    @Transactional
    public void addConcat(PhoneWhiteListRequest request) {
        //获取当前登录用户信息
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        //对电话号码进行合法校验
        if(!PhoneUtil.isValidPhoneNumber(request.getPhoneNumber())){
            throw new RuntimeException("电话号码格式错误");
        }
        DeviceInfo deviceInfo = deviceInfoService.getOne(new QueryWrapper<DeviceInfo>().eq("device_id", request.getDeviceId()));
        if(deviceInfo==null){
            throw new RuntimeException("设备不存在");
        }
        if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法修改定位模式");
        }
        PhoneWhitelist WhiteInfoByPhone = phoneWhitelistService.getOneByPhone(request.getPhoneNumber());
        if(WhiteInfoByPhone!=null){
            throw new RuntimeException("该号码已存在");
        }
        //去掉前后空格
        String name = request.getName();
        name=name.trim();
        //发送消息到设备
        T8401 t8401 = new T8401();
        t8401.setClientId(deviceInfo.getImei());
        t8401.setType(2);
        List<T8401.Contact> contacts=new ArrayList<>();
        contacts.add(new T8401.Contact( request.getSign(), request.getPhoneNumber(),name));
        t8401.setContacts( contacts);
        sendMessage2T8401(t8401);
        //添加信息到白名单
        PhoneWhitelist phoneWhitelist = new PhoneWhitelist();
        phoneWhitelist.setDeviceId(request.getDeviceId());
        phoneWhitelist.setPhoneNumber(request.getPhoneNumber());
        phoneWhitelist.setName(name);
        phoneWhitelist.setSign(request.getSign());
        phoneWhitelist.setAppUserId(appUser.getAppUserId());
        phoneWhitelistService.save(phoneWhitelist);
        log.info("添加白名单联系人成功");
    }


    /**
     * 删除联系人白名单
     * @param phoneId 联系人id
     * @return 响应结果
     */
    @Transactional
    public void deleteConcat(Long phoneId) {
        PhoneWhitelist whitelistInfo = phoneWhitelistService.getOne(new QueryWrapper<PhoneWhitelist>().eq("phone_id", phoneId).eq("data_status", 1));
        if(whitelistInfo==null) throw new RuntimeException("要删除的联系人信息不存在");
        Long deviceId = whitelistInfo.getDeviceId();
        //根据设备id查询电话名单列表
        List<PhoneWhitelist> phoneWhitelists = phoneWhitelistService.listByDeviceId(deviceId);
        //移除跟要删除的phoneId相同的电话名单
        phoneWhitelists.removeIf(phoneWhitelist -> phoneWhitelist.getPhoneId().equals(phoneId));

        //根据设备id查询设备信息获取imei号
        DeviceInfo deviceInfo = deviceInfoService.getOne(new QueryWrapper<DeviceInfo>().eq("device_id", deviceId));
        if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法修改定位模式");
        }
        String imei = deviceInfo.getImei();
        //发送消息给设备
        T8401 t8401 = new T8401();
        t8401.setClientId(imei);
        if(CollectionUtils.isEmpty(phoneWhitelists)){
            //过滤掉的电话名单为空，则全删
            t8401.setType(0);
        }else{
            t8401.setType(1);
            List<T8401.Contact> contacts=new ArrayList<>();
            for (PhoneWhitelist whitelist : phoneWhitelists) {
                T8401.Contact contact = new T8401.Contact();
                contact.setSign(whitelist.getSign());
                contact.setPhone(whitelist.getPhoneNumber());
                contact.setName(whitelist.getName());
                contacts.add(contact);
            }
            t8401.setContacts( contacts);
        }
        sendMessage2T8401(t8401);

        //删除该信息
        LambdaUpdateWrapper<PhoneWhitelist> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(PhoneWhitelist::getPhoneId, phoneId);
        phoneWhitelistService.remove(wrapper);
        log.info("删除白名单联系人成功");
    }

    /**
     * 发送T8401消息给设备
     * @param t8401 消息体
     */

    public void sendMessage2T8401(T8401 t8401){

        petServer808Service.T8401(t8401).doOnSuccess(apiResult -> {
                    if (apiResult != null && apiResult.getData() != null) {
                        T0001 response = apiResult.getData();
                        if (response.getResultCode() == 0 && Boolean.TRUE.equals(response.isSuccess())) {
                            log.info("消息接收成功:clientId：{}",t8401.getClientId());
                        } else {
                            log.error("消息接收失败，状态码: {},clientId:{}", response.getResultCode(),t8401.getClientId());
                        }
                    }else{
                        //走熔断了
                        log.error("发送消息走熔断了,设置联系人白名单,clientId:{}",t8401.getClientId());
                        //throw new RuntimeException("网络异常，请稍后重试");
                    }
                })
                .doOnError(throwable -> {
                    log.error("发送消息失败，设置联系人白名单");
                    throw new RuntimeException("网络异常，请稍后重试");
                })
                .subscribe(
                        result -> log.info("发送成功，设置联系人白名单4"),
                        throwable -> {
                            // 这里才是最终的错误处理入口
                            log.error("订阅失败，设置联系人白名单", throwable);
                            // 可再次更新状态或做其他处理
                        }
                );
    }

    /**
     * 修改联系人白名单
     * @param request 请求参数
     * @return 响应结果
     */
    public void updateConcat(PhoneWhiteListRequest request) {
        log.info("现在时间1：{}",System.currentTimeMillis());
        //获取用户信息
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        //对电话号码进行合法校验
        if(!PhoneUtil.isValidPhoneNumber(request.getPhoneNumber())){
            throw new RuntimeException("电话号码格式错误");
        }
        Long deviceId = request.getDeviceId();
        List<PhoneWhitelist> phoneWhitelists;
        if(deviceId!=null){
            //如果设备id不为空，则根据设备id查询
             phoneWhitelists = phoneWhitelistService.listByDeviceId(deviceId);
        }else{
            //如果设备id为空，则根据联系人id查询，然后在根据设备id查询集合信息
            PhoneWhitelist whitelistInfo = phoneWhitelistService.getOne(new QueryWrapper<PhoneWhitelist>().eq("phone_id", request.getPhoneId()).eq("data_status", 1));
            if(whitelistInfo==null) throw new RuntimeException("要修改的联系人信息不存在");
            deviceId = whitelistInfo.getDeviceId();
            phoneWhitelists = phoneWhitelistService.listByDeviceId(deviceId);
        }
        //根据设备id获取设备imei号
        DeviceInfo deviceInfo = deviceInfoService.getOne(new QueryWrapper<DeviceInfo>().eq("device_id", deviceId));
        if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法修改定位模式");
        }
        String imei = deviceInfo.getImei();
        //发送消息给设备
        T8401 t8401 = new T8401();
        t8401.setClientId(imei);
        t8401.setType(1);
        List<T8401.Contact> contacts=new ArrayList<>();
        phoneWhitelists.forEach(phoneWhitelist -> {
            T8401.Contact contact = new T8401.Contact();
            if(phoneWhitelist.getPhoneId().equals(request.getPhoneId())){
                phoneWhitelist.setName(request.getName());
                phoneWhitelist.setPhoneNumber(request.getPhoneNumber());
                phoneWhitelist.setSign(request.getSign());
            }
            contact.setSign(phoneWhitelist.getSign());
            contact.setPhone(phoneWhitelist.getPhoneNumber());
            contact.setName(phoneWhitelist.getName());
            contacts.add(contact);
        });
        t8401.setContacts( contacts);
        log.info("现在时间2：{}",System.currentTimeMillis());
        sendMessage2T8401(t8401);
        log.info("现在时间3：{}",System.currentTimeMillis());
        //更新电话名单信息
        phoneWhitelistService.lambdaUpdate()
                .eq(PhoneWhitelist::getPhoneId, request.getPhoneId())
                .set(PhoneWhitelist::getName, request.getName())
                .set(PhoneWhitelist::getPhoneNumber, request.getPhoneNumber())
                .set(PhoneWhitelist::getSign, request.getSign())
                .set(PhoneWhitelist::getAppUserId, appUser.getAppUserId())
                .update();
        log.info("现在时间4：{}",System.currentTimeMillis());
        log.info("更新白名单联系人成功");
    }

    /**
     * 查询联系人列表
     * @param deviceId 设备id
     * @param phoneNumber 电话号码
     * @param name 姓名
     * @param sign 类型(1,2,3)
     * @return List<PhoneWhiteListResponse>
     */
    public List<PhoneWhiteListResponse> list(Long deviceId, String phoneNumber, String name, String sign) {
        //sign为逗号分隔
        List<Integer> signList = new ArrayList<>();
        if(StringUtils.isNotBlank(sign)){
            String[] split = sign.split(",");
            for (String s : split) {
                signList.add(Integer.parseInt(s));
            }
        }
        LambdaQueryWrapper<PhoneWhitelist> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(PhoneWhitelist::getDeviceId, deviceId);
        lambdaQuery.like(StringUtils.isNotBlank(phoneNumber), PhoneWhitelist::getPhoneNumber, phoneNumber)
                .like(StringUtils.isNotBlank(name), PhoneWhitelist::getName, name)
                .in(StringUtils.isNotBlank(sign), PhoneWhitelist::getSign, signList);
        List<PhoneWhitelist> whitelistList = phoneWhitelistService.list(lambdaQuery);
        List<PhoneWhiteListResponse> responses=new ArrayList<>();
        if(CollectionUtils.isEmpty(whitelistList))
            return responses;
        whitelistList.forEach(whitelist -> {
            PhoneWhiteListResponse response = PhoneWhiteListResponse.transform(whitelist);
            response.setSignName(dictDataService.selectDictLabel("phone_white_list_sign", whitelist.getSign().toString()));
            responses.add(response);
        });
        return responses;
    }

    /**
     * 根据dictType查询通知类型
     * @param dictType 字典类型
     * @return List<NoticeTypeResponse>
     */
    public List<NoticeTypeResponse> queryNoticeTypeByDictType(String dictType) {
        List<SysDictData> sysDictDataList = dictDataService.selectDictDataByDictType(dictType);
        if(CollectionUtils.isEmpty(sysDictDataList)){
            return Collections.emptyList();
        }
        return sysDictDataList.stream().map(NoticeTypeResponse::transform).collect(Collectors.toList());
    }

    /**
     * 根据id查询联系人信息
     * @param phoneId 联系人id
     * @return PhoneWhiteListResponse
     */
    public PhoneWhiteListResponse queryById(Long phoneId) {
        PhoneWhitelist whitelist = phoneWhitelistService.getOne(new QueryWrapper<PhoneWhitelist>().eq("phone_id", phoneId).eq("data_status", 1));
        PhoneWhiteListResponse transform = PhoneWhiteListResponse.transform(whitelist);
        transform.setSignName(dictDataService.selectDictLabel("phone_white_list_sign", whitelist.getSign().toString()));
        return transform;
    }
}
